/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <iostream>
#include <memory>
#include <string>
#include <fstream>

#include <grpcpp/grpcpp.h>

#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "defs.grpc.pb.h"
#include "defs_self.grpc.pb.h"
#include "WingDCS.grpc.pb.h"
#endif

#include <unistd.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>

#include "/home/hcgy/Documents/esm6800h/app/can_uim.h"
#include "/home/hcgy/Documents/esm6800h/app/common.h"
#include "/home/hcgy/Documents/esm6800h/app/msg_def.h"
#include "/home/hcgy/Documents/esm6800h/test/data_proc/board_data_proc.h"

#include "action_msg.h"
#include "gp_beta_server.h"
#include "motor_config.h"
#include "gp_layout_map.h"
#include "sock_msg.h"
#include "spit_param.h"
#include "heat_config.h"
#include "parse_scheme.h"



using namespace std;

#define FILE_DJ_TRACE "/mnt/nandflash/apps/config/dj_trace.txt"


int g_msg_id = -1;

class DCSServiceImpl final : public DCSService::Service {

  Status MotorMove(ServerContext* context,const MotorMoveParam* request, CmdResponse* reply) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    int component = 0;
    msgHeadToSend.moduleType = request->moduletype();
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());
    component = request->motortype();
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_STEPS;

    //std::cout<<"module type:"<<
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,5000,nodeToCheck,reply);

    return Status::OK;
  }

  // Status SetScheme(ServerContext* context,const Scheme* request, CmdResponse* reply) override {
  
  //   return Status::OK;
  // }

  Status StartUpProc(ServerContext* context, const Void* request, CmdResponse* reply) override {
    return Status::OK;
  }


  // Status MoveToPos(ServerContext* context, const PosParam* request, CmdResponse* reply ) override {
    
  //   int moduleType = request->moduletype();

  //   int sid_z = get_sid(moduleType,MotorType::MT_AXIS_Z);
  //   int sid_jawz = get_sid(moduleType,MotorType::MT_JAW_Z);
  //   int actRet = 1;
  //   if(sid_z||sid_jawz)
  //   {
  //     move_param moveParam[2];
  //     int num = 0;
  //     memset(moveParam,0,sizeof(move_param)*2);

  //     if(sid_z)
  //     {
  //       moveParam[num].pos = request->zlimit();
  //       moveParam[num].dec_speed = 80000;
  //       moveParam[num].inc_speed = 80000;
  //       moveParam[num].speed = 20000;
  //       moveParam[num].sid = sid_z;
  //       num++;
  //     }

  //     if(sid_jawz && sid_z!=sid_jawz)
  //     {
  //       moveParam[num].pos = request->zlimit();
  //       moveParam[num].dec_speed = 80000;
  //       moveParam[num].inc_speed = 80000;
  //       moveParam[num].speed = 20000;
  //       moveParam[num].sid = sid_jawz;
  //       num++;
  //     }
      
  //      actRet = uimMoveAct_multi(moveParam,num,20000);
  //   }

  //   if(actRet != 1)
  //   {
  //       reply->set_returnval(ReturnVal::RET_FALSE);
  //       return Status::OK;
  //   }

  //   int sid_x = get_sid(moduleType,MotorType::MT_AXIS_X);
  //   int sid_y = get_sid(moduleType,MotorType::MT_AXIS_Y);

  //   // CGpLayout * pLayout = CGpLayout::get_instance();
  //   // location_layout paramIn;
  //   // paramIn.location_type = DP1_TIPS;
  //   // paramIn.indexX = 0;
  //   // paramIn.indexY = 0;
  //   // paramIn.row_x = 2;
  //   // paramIn.column_y = 3;

  //   // location_axis locResult;


  //   //int convertRet = pLayout->convertToAxisLoc(&paramIn,&locResult);

  //   if(sid_x||sid_y)
  //   {
  //     move_param moveParam[2];
  //     int num = 0;
  //     memset(moveParam,0,sizeof(move_param)*2);

  //     if(sid_x)
  //     {
  //       moveParam[num].pos = request->zlimit();
  //       moveParam[num].dec_speed = 80000;
  //       moveParam[num].inc_speed = 80000;
  //       moveParam[num].speed = 20000;
  //       moveParam[num].sid = sid_x;
  //       num++;
  //     }

  //     if(sid_y && sid_y!=sid_x)
  //     {
  //       moveParam[num].pos = request->zlimit();
  //       moveParam[num].dec_speed = 80000;
  //       moveParam[num].inc_speed = 80000;
  //       moveParam[num].speed = 20000;
  //       moveParam[num].sid = sid_y;
  //       num++;
  //     }
      
  //     actRet = uimMoveAct_multi(moveParam,num,20000);
  //   }

  //   if(actRet != 1)
  //   {
  //       reply->set_returnval(ReturnVal::RET_FALSE);
  //       return Status::OK;
  //   }
    


  //   return Status::OK;
  // }

  // Status StartGrpPurifyScheme(ServerContext* context, const PurifyScheme* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }
  
  Status BuildPCRBoard(ServerContext* context, const BuildPCRParam* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  // Status StartPCRScheme(ServerContext* context, const PCRScheme* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  Status Maintain(ServerContext* context, const MaintainParam* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  Status ExecTimeSerial(ServerContext* context, const TimeSerialParam* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  Status Pause(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  Status DebugAddAlarm(ServerContext* context, const AlarmParam* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  Status GetDCSVersion(ServerContext* context, const Void* request, StrResponse* reply ) override {
    return Status::OK;
  }

  Status GetDCSLog(ServerContext* context, const Void* request, StrResponse* reply ) override {
    return Status::OK;
  }

  Status GetShakeBlocksSpeed(ServerContext* context, const Void* request, SpeedParam* reply ) override {
    return Status::OK;
  }

  Status GetShakeBlocksTemperature(ServerContext* context, const Void* request, TemperaturePara* reply ) override {
    return Status::OK;
  }

  Status GetFansSpeed(ServerContext* context, const Void* request, SpeedParam* reply ) override {
    return Status::OK;
  }
 
  Status GetAllDiffPress(ServerContext* context, const Void* request, DiffPressParam* reply ) override {
    return Status::OK;
  }

  Status StopDebug(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    return Status::OK;
  } 

  Status SetFixPos(ServerContext* context, const Position* request, CmdResponse* reply ) override {
    //save current position to config file.
    return Status::OK;
  }

  Status GetTemp(ServerContext* context, const GetTempParam* request, CmdResponse* reply ) override {
        sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    int component = 0;
    convertTempPos(request->tempos(),msgHeadToSend.moduleType,component);
    //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TEMPERATURE_READ;
    msgHeadToSend.paramType = component;
    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,5000,nodeToCheck,reply);

    return Status::OK;
  }
  
  Status PlungerPumpCtrl(ServerContext* context, const PlungerPumpCtrlParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in PlungerPumpCtrl"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));

    int component = GPRPC::MotorType::MT_PUMP;

    if(request->pumptype() == GPRPC::PumpType::DJ1_PUMP)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DJ1_PCR_REAGENT;
    }
    else if(request->pumptype() == GPRPC::PumpType::DJ2_PUMP_BIG
    ||request->pumptype() == GPRPC::PumpType::DJ2_PUMP_SMALL)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DJ2_PU_REAGENT;

        if(request->pumptype() == GPRPC::PumpType::DJ2_PUMP_SMALL)
        {
          component = GPRPC::MotorType::MT_PUMP_SMALL;
        }         
    }
    else if(request->pumptype() == GPRPC::PumpType::DP8_PUMP_8)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8;         
    }
    else if(request->pumptype() == GPRPC::PumpType::DP8_PUMP_1)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8_1;         
    }
    else if(request->pumptype() == GPRPC::PumpType::DP1_PUMP)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP1;         
    }
    else
    {
      std::cout << "in PlungerPumpCtrl,pumpType is invalid,"<<request->pumptype()<<std::endl;
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }


    //msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PLUNGER_PUMP;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);   

    return Status::OK;
  }

  Status MotorPos(ServerContext* context, const MotorPosParam* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int component = request->motortype();
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;
    
  }

  Status MotorInit(ServerContext* context, const Motor* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SINGLE_INIT;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int component = request->motortype();
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;
  }

  Status ModuleInit(ServerContext* context, const ModuleName* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_MODULE_INIT;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int component = -1;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;
  }

  // Status ModuleMove(ServerContext* context, const ModuleMoveParam* request, CmdResponse* reply ) override {
    
  //   int moduleType = request->moduletype();
    
  //   int actRet = 1;


  //   int sid_z = get_sid(moduleType,MotorType::MT_AXIS_Z);
  //   int sid_jawz = get_sid(moduleType,MotorType::MT_JAW_Z);
    
  //   std::cout<<"sid_z:"<<sid_z<<",sid_jawz:"<<sid_jawz<<std::endl;
  //   // if(sid_z||sid_jawz)
  //   // {
  //   //   move_param moveParam[2];
  //   //   int num = 0;
  //   //   memset(moveParam,0,sizeof(move_param)*2);

  //   //   if(sid_z)
  //   //   {
  //   //     moveParam[num].pos = 0;
  //   //     moveParam[num].dec_speed = 80000;
  //   //     moveParam[num].inc_speed = 80000;
  //   //     moveParam[num].speed = 20000;
  //   //     moveParam[num].sid = sid_z;
  //   //     num++;
  //   //   }

  //   //   if(sid_jawz && sid_z!=sid_jawz)
  //   //   {
  //   //     moveParam[num].pos = 0;
  //   //     moveParam[num].dec_speed = 80000;
  //   //     moveParam[num].inc_speed = 80000;
  //   //     moveParam[num].speed = 20000;
  //   //     moveParam[num].sid = sid_jawz;
  //   //     num++;
  //   //   }
      
  //   //    actRet = uimMoveAct_multi(moveParam,num,20000);
  //   // }
    



  //   if(actRet != 1)
  //   {
  //       reply->set_returnval(ReturnVal::RET_FALSE);
  //       return Status::OK;
  //   }

  //   int sid_x = get_sid(moduleType,MotorType::MT_AXIS_X);
  //   int sid_y = get_sid(moduleType,MotorType::MT_AXIS_Y);

  //   location_axis locResult;

  //   int convertRet = convertPosition(moduleType,request->pos(),&locResult);
  //   if(convertRet)
  //   {
  //     std::cout << "convert position failed"<<std::endl;
  //   }
  //   else
  //   {
  //     std::cout <<"distance, sidx:"<<sid_x<<",x_pos:"<<locResult.x
  //       <<",sidy:"<<sid_y<<",y:"<<locResult.y <<std::endl;
  //   }


  //   if(sid_x||sid_y)
  //   {
  //     // move_param moveParam[2];
  //     // int num = 0;
  //     // memset(moveParam,0,sizeof(move_param)*2);

  //     // if(sid_x)
  //     // {
  //     //   moveParam[num].pos = locResult.x;
  //     //   moveParam[num].dec_speed = 80000;
  //     //   moveParam[num].inc_speed = 80000;
  //     //   moveParam[num].speed = 20000;
  //     //   moveParam[num].sid = sid_x;
  //     //   num++;
  //     // }

  //     // if(sid_y && sid_y!=sid_x)
  //     // {
  //     //   moveParam[num].pos = locResult.y;
  //     //   moveParam[num].dec_speed = 80000;
  //     //   moveParam[num].inc_speed = 80000;
  //     //   moveParam[num].speed = 20000;
  //     //   moveParam[num].sid = sid_y;
  //     //   num++;
  //     // }
      
  //     // actRet = uimMoveAct_multi(moveParam,num,20000);

  //   }//end of if(sid_x||sid_y)

  //   if(actRet != 1)
  //   {
  //     reply->set_returnval(ReturnVal::RET_FALSE);
  //     return Status::OK;
  //   }
  //   else
  //   {
  //     reply->set_returnval(ReturnVal::RET_TRUE);
  //     return Status::OK;
  //   }

  // }
  Status ModuleMove(ServerContext* context, const ModuleMoveParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in ModuleMove"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status MoveLogistics1Tray(ServerContext* context, const PosTypeParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in MoveLogistics1Tray"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG1;

    int convertRet = convertLogicPostype(logMoveParam.submodule,request->postype());
    if(convertRet < 0)
    {
      std::cout<<"convert logistic pos type failed"<<std::endl;
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;      
    }
    logMoveParam.posTypeInner = convertRet;


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  
  Status MoveLogistics2Tray(ServerContext* context, const TransParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in MoveLogistics2Tray"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG2;

    int convertRet = convertLogicPostype(logMoveParam.submodule,request->pos());
    if(convertRet < 0)
    {
      if(request->transtype() == GPRPC::TRANS_LEFT)
      {
        logMoveParam.posTypeInner = LOG2_EXCHANGE_BEFORE;
      }
      else
      {
        logMoveParam.posTypeInner = LOG2_EXCHANGE_AFTER;
      }
      // std::cout<<"convert logistic pos type failed"<<std::endl;
      // reply->set_returnval(ReturnVal::RET_FALSE);
      // return Status::OK;      
    }
    else
    {
      logMoveParam.posTypeInner = convertRet;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }
  
  Status MoveLogistics3Tray(ServerContext* context, const PosTypeParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in MoveLogistics3Tray"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG3;

    int convertRet = convertLogicPostype(logMoveParam.submodule,request->postype());
    if(convertRet < 0)
    {
      std::cout<<"convert logistic pos type failed"<<std::endl;
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;      
    }
    logMoveParam.posTypeInner = convertRet;


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status FrontTrayTo2RdTrans(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in FrontTrayTo2RdTrans"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG2;
    logMoveParam.posTypeInner = LOG2_EXCHANGE_BEFORE;


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,40000,nodeToCheck,reply);

    return Status::OK; 
  }

  
  Status BackTrayTo2RdTrans(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in BackTrayTo2RdTrans"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG2;
    logMoveParam.posTypeInner = LOG2_EXCHANGE_AFTER;

    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,40000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status Logistics1ToLogistics2(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in Logistics1ToLogistics2"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TRANS_BOARD;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam[2];
    logMoveParam[0].submodule = SUB_MODULE_LOG1;
    logMoveParam[0].posTypeInner = LOG1_PCR_BOARD;

    logMoveParam[1].submodule = SUB_MODULE_LOG1;
    logMoveParam[1].posTypeInner = LOG1_EXCHANGE12;

    sendToActAndWaitResp(&msgHeadToSend, logMoveParam,40000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status Logistics2ToLogistics3(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in Logistics2ToLogistics3"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
  
    logMoveParam.submodule = SUB_MODULE_LOG2;
    logMoveParam.posTypeInner = LOG2_EXCHANGE23;

    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  
  Status Logistics2HeatSealBefore(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in Logistics2HeatSealBefore"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TRANS_BOARD;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam[2];
    logMoveParam[0].submodule = SUB_MODULE_LOG2;
    logMoveParam[0].posTypeInner = LOG2_EXCHANGE12;

    logMoveParam[1].submodule = SUB_MODULE_LOG2;
    logMoveParam[1].posTypeInner = LOG2_EXCHANGE_BEFORE;

    sendToActAndWaitResp(&msgHeadToSend, logMoveParam,40000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status Logistics2HeatSealAfter(ServerContext* context, const Void* request, CmdResponse* reply ) override {
    std::cout<<"enter in Logistics2HeatSealAfter"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TRANS_BOARD;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam[2];
    logMoveParam[0].submodule = SUB_MODULE_LOG2;
    logMoveParam[0].posTypeInner = LOG2_EXCHANGE12;

    logMoveParam[1].submodule = SUB_MODULE_LOG2;
    logMoveParam[1].posTypeInner = LOG2_EXCHANGE_AFTER;

    sendToActAndWaitResp(&msgHeadToSend, logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status LogisticsTest(ServerContext* context, const MovePcrParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in LogisticsTest"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TRANS_BOARD;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam[2];
    
    logMoveParam[0].submodule = SUB_MODULE_LOG2;
    logMoveParam[0].posTypeInner = LOG2_EXCHANGE12;

    logMoveParam[1].submodule = SUB_MODULE_LOG2;
    logMoveParam[1].posTypeInner = LOG2_EXCHANGE_AFTER;

    int conRet = convertLogicTranPos(request, logMoveParam);

    if(conRet)
    {      
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;      
    }

    sendToActAndWaitResp(&msgHeadToSend, logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status MoveVerticalBarcodeScanner(ServerContext* context, const BarcodeScannerPos* request, CmdResponse* reply ) override {
    std::cout<<"enter in MoveVerticalBarcodeScanner"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    if(request->scannertype() == GPRPC::ScannerType::REAGENT_CLEAN_SCANNER)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8;
    }
    else if(request->scannertype() == GPRPC::ScannerType::CONSUMABLE_PCR_SCANNER)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DJ1_PCR_REAGENT;
    }

    //convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    ModuleMoveParam pstParam;
    Position * posTarget = new Position;
    posTarget->CopyFrom(request->pos());
    pstParam.set_allocated_pos(posTarget);
    pstParam.set_moduletype(GPRPC::ModuleType(msgHeadToSend.moduleType));


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &pstParam,20000,nodeToCheck,reply);


    pstParam.clear_pos();

    return Status::OK; 
  }

  Status JawGetPut(ServerContext* context, const JawGetPutParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in JawGetPut"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_CTL;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);    
    return Status::OK;
  }


  Status GetPutFilm(ServerContext* context, const GetPutFilmParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in GetPutFilm"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_CTL_FILM;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);    
    return Status::OK;
  }
  

  Status JawMove(ServerContext* context, const JawMoveParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in JawMove"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_TRANS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,80000,nodeToCheck,reply);
    
    return Status::OK;
  }

  Status MoveFilm(ServerContext* context, const GetFilmParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in MoveFilm"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_TRANS_FILM;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }
    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);
    
    return Status::OK;
  }

  Status DjDpLiquidCtrl(ServerContext* context, const DjDpLiquidCtrlParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in DjDpLiquidCtrl"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    if(request->pumpctrl() == GPRPC::PumpCtrl::PICKUP)
    {
      msgHeadToSend.actType = ACT_SUCK_LIQUID;

      msgHeadToSend.paramType = PARAM_LIQUID_CTL;
      int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
      

      // if(!checkActReady(actId))
      // {
      //    reply->set_returnval(ReturnVal::RET_REJECT);
      //    return Status::OK;
      // }

      sock_act_ctl ctlData;
      ctlData.actId = actId;
      ctlData.expectDataType = EXPECT_NO_DATA;
      ctlData.status = LUA_ACT_WAITING;

      act_ctl_node *nodeToCheck = setExpectData(&ctlData);

      if(nodeToCheck == NULL)
      {
        //action already running.
        reply->set_returnval(ReturnVal::RET_REJECT);
        return Status::OK;
      }

      //sendSockMsgToAct(&msgHeadToSend, request);
      sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    }
    else if(request->pumpctrl() == GPRPC::PumpCtrl::SPIT)
    {
        msgHeadToSend.actType = ACT_SPIT_LIQUID;

        pos_type_list tmpPosList;
        memset(&tmpPosList,0,sizeof(pos_type_list));
        int totalSpitVolume = 0;
        int divideRet =  divideSpitPos(request,PARAM_LIQUID_CTL,&tmpPosList,&totalSpitVolume);         
              
        if(divideRet)
        {
            printf("devide spit positions failed\n");
            reply->set_returnval(ReturnVal::RET_REJECT);
            clearSpitParamList(&tmpPosList);
            return Status::OK;                
        }
        //printDivideResult(&tmpPosList);

        pos_one_type * pstOneSpitList = tmpPosList.listHead;
        while(pstOneSpitList!=NULL)
        {
          msgHeadToSend.paramType = PARAM_LIQUID_CTL;
          msgHeadToSend.moduleType = request->moduletype();
          int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
          

          // if(!checkActReady(actId))
          // {
          //    reply->set_returnval(ReturnVal::RET_REJECT);
          //    return Status::OK;
          // }

          sock_act_ctl ctlData;
          ctlData.actId = actId;
          ctlData.expectDataType = EXPECT_NO_DATA;
          ctlData.status = LUA_ACT_WAITING;

          act_ctl_node *nodeToCheck = setExpectData(&ctlData);

          if(nodeToCheck == NULL)
          {
            //action already running.
            reply->set_returnval(ReturnVal::RET_REJECT);
            break;
          }

          //sendSockMsgToAct(&msgHeadToSend, request);
          sendToActAndWaitResp(&msgHeadToSend, pstOneSpitList,20000,nodeToCheck,reply);
          if(reply->returnval()!=ReturnVal::RET_TRUE)
          {
            break;
          }
          pstOneSpitList = pstOneSpitList->next;
        }

        clearSpitParamList(&tmpPosList);
      
    }
    else 
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    return Status::OK;
  }
  
  Status DjDpSuckASpit(ServerContext* context, const DjDpSuckASpitParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in DjDpSuckASpit"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());

    msgHeadToSend.actType = ACT_SUCK_LIQUID;

    msgHeadToSend.paramType = PARAM_SUCK1_SPIT1;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // DjDpLiquidCtrlParam stLiquidCtlParam;
    // stLiquidCtlParam.set_moduletype(request->moduletype());
    // GPRPC::Position * posSuck =  stLiquidCtlParam.add_pos();
    // posSuck->CopyFrom(request->pickuppos());
    // stLiquidCtlParam.set_volum(request->pickupvolum());

    sendToActAndWaitResp(&msgHeadToSend, request,40000,nodeToCheck,reply);

    if(reply->returnval() != ReturnVal::RET_TRUE)
    {
      return  Status::OK;
    }

    //here suck finished
    msgHeadToSend.actType = ACT_SPIT_LIQUID;
    msgHeadToSend.moduleType = request->moduletype();
    pos_type_list tmpPosList;
    memset(&tmpPosList,0,sizeof(pos_type_list));
    

    tmpPosList.listHead = new pos_one_type;
    memset(tmpPosList.listHead,0,sizeof(pos_one_type));
    tmpPosList.listTail = tmpPosList.listHead;
    pos_one_type * pstOneSpitList = tmpPosList.listHead;


    
    pos_spit * nodeSpitPos = new pos_spit;
    memset(nodeSpitPos,0,sizeof(pos_spit));
    nodeSpitPos->column_x = request->spiteparam().pos().column();
    nodeSpitPos->row_y = request->spiteparam().pos().row();
    nodeSpitPos->index = request->spiteparam().pos().index();
    nodeSpitPos->volume = request->spiteparam().volum();

    pstOneSpitList->num = 1;
    pstOneSpitList->posType = request->spiteparam().pos().postype();

    pstOneSpitList->posListHead = nodeSpitPos;
    pstOneSpitList->posListTail = nodeSpitPos;
    pstOneSpitList->remainVolume = request->spiteparam().existv();
    pstOneSpitList->tipType = request->spiteparam().tiptype();
    while(pstOneSpitList!=NULL)
    {
      msgHeadToSend.paramType = PARAM_SUCK1_SPIT1;
      msgHeadToSend.moduleType = request->moduletype();
      int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
      

      // if(!checkActReady(actId))
      // {
      //    reply->set_returnval(ReturnVal::RET_REJECT);
      //    return Status::OK;
      // }

      sock_act_ctl ctlData;
      ctlData.actId = actId;
      ctlData.expectDataType = EXPECT_NO_DATA;
      ctlData.status = LUA_ACT_WAITING;

      act_ctl_node *nodeToCheck = setExpectData(&ctlData);

      if(nodeToCheck == NULL)
      {
        //action already running.
        reply->set_returnval(ReturnVal::RET_REJECT);
        break;
      }

      //sendSockMsgToAct(&msgHeadToSend, request);
      sendToActAndWaitResp(&msgHeadToSend, pstOneSpitList,80000,nodeToCheck,reply);
      if(reply->returnval()!=ReturnVal::RET_TRUE)
      {
        break;
      }
      pstOneSpitList = pstOneSpitList->next;
    }

    clearSpitParamList(&tmpPosList);
      

    return Status::OK;
  }

Status djAddSample(const DjDpSuckMoreSpitParam* request, CmdResponse* reply)
{
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());

    msgHeadToSend.actType = ACT_SUCK1_SPITM;
    msgHeadToSend.paramType = PARAM_SUCK1_SPIT_MULTI;

    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      //clearSpitParamList(&tmpPosList);
      return Status::OK;
    }
    
    
    pos_type_list tmpPosList;
    memset(&tmpPosList,0,sizeof(pos_type_list));

    int totalSpitVolume = 0;
    int divideRet =  divideSpitPos(request,PARAM_SUCK1_SPIT_MULTI,&tmpPosList,&totalSpitVolume);         
    
    
    if(divideRet)
    {
        printf("devide spit positions failed\n");
        reply->set_returnval(ReturnVal::RET_REJECT);
        clearSpitParamList(&tmpPosList);
        return Status::OK;                
    }

    int suckVolume = request->pickupparam().volum();

    if(suckVolume <= totalSpitVolume)
    {
        printf("suck volume is not enough\n");
        reply->set_returnval(ReturnVal::RET_REJECT);
        clearSpitParamList(&tmpPosList);
        return Status::OK;  
    }

    GPRPC::MoveLiquidParam pstSuckParam;

    pstSuckParam.CopyFrom(request->pickupparam());

    int volumeDone = 0;
    int volumeMaxOnce = 500;
    //adjust volumeMaxOnce according to the suck pos

    if(msgHeadToSend.moduleType == GPRPC::ModuleType::MT_DJ1_PCR_REAGENT)
    {
      volumeMaxOnce = 2500;
    }
    else if(pstSuckParam.pos().row() == 6 || pstSuckParam.pos().row() == 7 )
    {
      volumeMaxOnce = 5000;
    }
    else 
    {
      volumeMaxOnce = 250;
    }
    int volumeOnce = 0;

    int isFirst = 1;

    pos_one_type * ptrOneSpitM = tmpPosList.listHead;
    pos_spit * ptrSpitPos = NULL;
    pos_spit * ptrSpitPosPrev = NULL;
    pos_spit * ptrSpitPosStart = NULL;
    pos_spit * ptrSpitPosEnd = NULL;

    param_suck1_spitm suck1SpitmParam;

    pos_one_type stOneSpitMToAct;
    stOneSpitMToAct.num = 0; 

    while(ptrOneSpitM)
    {
        ptrSpitPos = ptrOneSpitM->posListHead;
        ptrSpitPosStart = ptrSpitPos;

        stOneSpitMToAct.posType = ptrOneSpitM->posType;
        stOneSpitMToAct.remainVolume = ptrOneSpitM->remainVolume;
        stOneSpitMToAct.tipType = ptrOneSpitM->tipType;
        while(ptrSpitPos)
        {
            volumeOnce += ptrSpitPos->volume;
            if(volumeOnce > volumeMaxOnce)
            {
                ptrSpitPosEnd = ptrSpitPosPrev;
                //send one msg and wait here.
                //suckloc|suckvolume|liquidtype|remainvolume|spitloc|spitvolume|ismulti|remainvolume|xyv...xyv
                pstSuckParam.set_volum(volumeOnce-ptrSpitPos->volume);
                suck1SpitmParam.stSuckParam = &pstSuckParam;
                suck1SpitmParam.pSpitMOnce = &stOneSpitMToAct;
                stOneSpitMToAct.posListHead = ptrSpitPosStart;
                stOneSpitMToAct.posListTail = ptrSpitPosEnd;
                stOneSpitMToAct.next = NULL;

                msgHeadToSend.moduleType = request->moduletype();
                if(!isFirst)
                {
                    nodeToCheck = setExpectData(&ctlData);

                    if(nodeToCheck == NULL)
                    {
                      //action already running.
                      reply->set_returnval(ReturnVal::RET_REJECT);
                      clearSpitParamList(&tmpPosList);
                      return Status::OK;
                    }
                }
                else
                {
                  isFirst = 0;
                }
                sendToActAndWaitResp(&msgHeadToSend, &suck1SpitmParam,180000,nodeToCheck,reply);

                if(reply->returnval() != ReturnVal::RET_TRUE)
                {
                  clearSpitParamList(&tmpPosList);
                  return  Status::OK;
                }

                ptrSpitPosStart = ptrSpitPos;
                volumeOnce = ptrSpitPos->volume;
                stOneSpitMToAct.num = 1;
            }
            stOneSpitMToAct.num++;
            ptrSpitPosPrev = ptrSpitPos;
            ptrSpitPos = ptrSpitPos->next;
        }
        //spit pos for one type end.
        ptrSpitPosEnd = ptrSpitPosPrev;
        //send one msg and wait here.
        //suckloc|suckvolume|liquidtype|remainvolume|spitloc|spitvolume|ismulti|remainvolume|xyv...xyv
        pstSuckParam.set_volum(volumeOnce);
        suck1SpitmParam.stSuckParam = &pstSuckParam;
        suck1SpitmParam.pSpitMOnce = &stOneSpitMToAct;
        stOneSpitMToAct.posListHead = ptrSpitPosStart;
        stOneSpitMToAct.posListTail = ptrSpitPosEnd;
        stOneSpitMToAct.next = NULL;

        msgHeadToSend.moduleType = request->moduletype();
        if(!isFirst)
        {
            nodeToCheck = setExpectData(&ctlData);

            if(nodeToCheck == NULL)
            {
              //action already running.
              reply->set_returnval(ReturnVal::RET_REJECT);
              clearSpitParamList(&tmpPosList);
              return Status::OK;
            }
        }
        else
        {
          isFirst = 0;
        }
        sendToActAndWaitResp(&msgHeadToSend, &suck1SpitmParam,180000,nodeToCheck,reply);

        if(reply->returnval() != ReturnVal::RET_TRUE)
        {
          clearSpitParamList(&tmpPosList);
          return  Status::OK;
        }

        //ptrSpitPosStart = ptrSpitPos;
        volumeOnce = 0;
        stOneSpitMToAct.num = 0;
          //send one msg and wait here.
        ptrOneSpitM = ptrOneSpitM->next;
    }


	return  Status::OK;
}

  Status DjDpSuckMoreSpit(ServerContext* context, const DjDpSuckMoreSpitParam* request, CmdResponse* reply ) override {
        std::cout<<"enter in DjDpSuckMoreSpit"<<std::endl;
    
    if(request->moduletype() == GPRPC::ModuleType::MT_DJ1_PCR_REAGENT
      ||request->moduletype() == GPRPC::ModuleType::MT_DJ2_PU_REAGENT)
    {
       return djAddSample(request, reply); 
    }
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());

    msgHeadToSend.actType = ACT_SUCK_LIQUID;

    msgHeadToSend.paramType = PARAM_SUCK1_SPIT_MULTI;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    std::cout<<"in DjDpSuckMoreSpit, tiptype:"<<request->pickupparam().tiptype()<<std::endl;

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    sendToActAndWaitResp(&msgHeadToSend, request,40000,nodeToCheck,reply);

    if(reply->returnval() != ReturnVal::RET_TRUE)
    {
      return  Status::OK;
    }

    //here suck finished
    
    msgHeadToSend.actType = ACT_SPIT_LIQUID_MULTI;
    msgHeadToSend.moduleType = request->moduletype();
    pos_type_list tmpPosList;
    memset(&tmpPosList,0,sizeof(pos_type_list));

    int totalSpitVolume = 0;

    int divideRet =  divideSpitPos(request,PARAM_SUCK1_SPIT_MULTI,&tmpPosList,&totalSpitVolume);         
          
    if(divideRet)
    {
        printf("devide spit positions failed\n");
        reply->set_returnval(ReturnVal::RET_REJECT);
        clearSpitParamList(&tmpPosList);
        return Status::OK;                
    }
    printDivideResult(&tmpPosList);

    pos_one_type * pstOneSpitList = tmpPosList.listHead;
    while(pstOneSpitList!=NULL)
    {
      msgHeadToSend.paramType = PARAM_SUCK1_SPIT_MULTI;
      msgHeadToSend.moduleType = request->moduletype();
      int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
      

      sock_act_ctl ctlData;
      ctlData.actId = actId;
      ctlData.expectDataType = EXPECT_NO_DATA;
      ctlData.status = LUA_ACT_WAITING;

      act_ctl_node *nodeToCheck = setExpectData(&ctlData);

      if(nodeToCheck == NULL)
      {
        //action already running.
        reply->set_returnval(ReturnVal::RET_REJECT);
        break;
      }

      //sendSockMsgToAct(&msgHeadToSend, request);
      sendToActAndWaitResp(&msgHeadToSend, pstOneSpitList,80000,nodeToCheck,reply);
      if(reply->returnval()!=ReturnVal::RET_TRUE)
      {
        break;
      }
      pstOneSpitList = pstOneSpitList->next;
    }

    clearSpitParamList(&tmpPosList);


    return Status::OK;
  }

  Status DpTipCtrl(ServerContext* context, const DpTipCtrlParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in DpTipCtrl" <<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_TIP_CTL;
    
    if(request->oper() == GPRPC::TipOper::GET)
    {
      msgHeadToSend.paramType = PARAM_GET_TIP;
    }
    else if(request->oper() == GPRPC::TipOper::QUIT)
    {
      msgHeadToSend.paramType = PARAM_DROP_TIP;
    }
    else
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }
    
    int component = -1;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;

  }

  Status DjPumpValveSwitch(ServerContext* context, const DjPumpValveSwitchParam* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.paramType = 0;

    if(msgHeadToSend.moduleType!=GPRPC::MT_DJ1_PCR_REAGENT 
    && msgHeadToSend.moduleType!=GPRPC::MT_DJ2_PU_REAGENT)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;      
    }
    
    msgHeadToSend.actType = ACT_DJ_CLEAN_CTL;
    int component = request->pumpvalvetype();
    
    //adjust the 
    if(component == GPRPC::V_IN_CLEAN_SMALL)
    {
      msgHeadToSend.moduleType = GPRPC::MT_DJ2_PU_REAGENT;
    }
    else if(component == GPRPC::P_MAG_WASTE)
    {
      msgHeadToSend.moduleType = GPRPC::MT_DJ1_PCR_REAGENT;
      component = GPRPC::P_WASTE; 
    }
    else if(component == GPRPC::P_RESERVED)
    {
      msgHeadToSend.moduleType = GPRPC::MT_DJ1_PCR_REAGENT;
      component = GPRPC::V_IN_CLEAN_SMALL; 
    }
	else if(component == GPRPC::P_WASTE)
    {
      msgHeadToSend.moduleType = GPRPC::MT_DJ2_PU_REAGENT;
    }

    msgHeadToSend.paramType = component;
    
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,5000,nodeToCheck,reply);    
    return Status::OK;
  }

  Status DjPumpValveWork(ServerContext* context, const DjPumpValveWorkParam* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.paramType = 90;

    if(request->cleanpos() == GPRPC::CleanPos::INNER)
    {
        msgHeadToSend.paramType -= 1;
    }
    else if(request->cleanpos() == GPRPC::CleanPos::EXINE)
    {
        msgHeadToSend.paramType -= 2;
    }

    if(msgHeadToSend.moduleType!=GPRPC::MT_DJ1_PCR_REAGENT 
    && msgHeadToSend.moduleType!=GPRPC::MT_DJ2_PU_REAGENT)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;      
    }
    
    msgHeadToSend.actType = ACT_DJ_CLEAN_CTL;
    int component = msgHeadToSend.paramType;
    
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,200000,nodeToCheck,reply);    
    return Status::OK;
    return Status::OK;
  }

  Status DjPumpValveInit(ServerContext* context, const ModuleName* request, CmdResponse* reply ) override {
    return Status::OK;
  }

  Status DjClean(ServerContext* context, const ModuleName* request, CmdResponse* reply ) override {
        sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.paramType = 90;

    if(msgHeadToSend.moduleType!=GPRPC::MT_DJ1_PCR_REAGENT 
    && msgHeadToSend.moduleType!=GPRPC::MT_DJ2_PU_REAGENT)
    {
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;      
    }
    
    msgHeadToSend.actType = ACT_DJ_CLEAN_CTL;
    int component = msgHeadToSend.paramType;
    
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,200000,nodeToCheck,reply);    
    return Status::OK;
  }

  Status ShakeHeatHeating(ServerContext* context, const ShakeHeatParam* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_HEAT_CTL;
    std::cout<<"enter in ShakeHeatHeating"<<std::endl;
    // if(request->oper() == GPRPC::SHAKE)
    // {
    //   msgHeadToSend.actType = ACT_SHAKE_CTL;
    // }
    // else if(request->oper() == GPRPC::MAGNETIC)
    // {
    //   msgHeadToSend.actType = ACT_SINGLE_MOVE;
    // }
    
    int component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.
    int actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
    
    heat_ctl stHeatCtl;
    stHeatCtl.chanNum = component;
    stHeatCtl.isClose = (request->switch_() == GPRPC::CLOSE)?1:0;
    stHeatCtl.temperature = request->heattemp();
    printf("in ShakeHeatHeating,temperature:%f\n",stHeatCtl.temperature);
    sendToActAndWaitResp(&msgHeadToSend, &stHeatCtl,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;     
  }

  Status ShakeMagneticSingOper(ServerContext* context, const ShakeMagneticSingOperParam* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;
    std::cout<<"enter in ShakeMagneticSingOper"<<std::endl;
    // if(request->oper() == GPRPC::SHAKE)
    // {
    //   msgHeadToSend.actType = ACT_SHAKE_CTL;
    // }
    // else if(request->oper() == GPRPC::MAGNETIC)
    // {
    //   msgHeadToSend.actType = ACT_SINGLE_MOVE;
    // }
    
    int component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.

    if(request->oper() == GPRPC::SHAKE)
    {
      component += 16;
    }
    int actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
       switch_ctl switchCtl;
       switchCtl.chanNum = component;
       switchCtl.isClose = (request->switch_() == GPRPC::CLOSE)?1:0;
       switchCtl.duration = request->opertime();
    
       sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;    
  } 

  Status ShakeMagnetic(ServerContext* context, const ShakeMagneticParam* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));

    
    int component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.
    int actId = 0;//calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = NULL;

    

    //1, start shake here;
        //sockActMsg msgHeadToSend;

    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;
    
    component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.

    //if(request->oper() == GPRPC::SHAKE)
    //{
    component += 16;
    //}
    actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
  

    //sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }


    switch_ctl switchCtl;
    switchCtl.chanNum = component;
    switchCtl.isClose = 0;
    switchCtl.duration = 0;//request->shaketime();


    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeMagnetic, start shake failed"<<std::endl;
      return Status::OK;
    }
    //2,sleep here
    int shake_time_ms = request->shaketime();
    if(shake_time_ms <= 500)
    {
      shake_time_ms = 5000;
    }
    usleep(1000*(shake_time_ms-500));
    //2.1 stop shake here;
    switchCtl.chanNum = component;
    switchCtl.isClose = 1;
    switchCtl.duration = 0;//request->shaketime();

    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeMagnetic, stop shake failed"<<std::endl;
      return Status::OK;
    }
    //std::cout<<"stop shake success"<<std::endl;
    //3,start smooth here

    component = request->index();
    actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
  

    //sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;

    switchCtl.chanNum = component;
    switchCtl.isClose = 0;
    switchCtl.duration = 0;//request->magnetictime();//request->shaketime();
    //std::cout<<"start magic smooth here,component:"<<component<<std::endl;
    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,20000,nodeToCheck,reply);     
    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeMagnetic, start magic smooth failed"<<std::endl;
      return Status::OK;
    }
    int magic_time_ms = request->magnetictime();
    if(magic_time_ms <= 500)
    {
      magic_time_ms = 5000;
    }
    usleep((magic_time_ms-500)*1000);

    //4, stop magic smooth here 
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;

    switchCtl.chanNum = component;
    switchCtl.isClose = 1;
    switchCtl.duration = 0;//request->magnetictime();//request->shaketime();
    //std::cout<<"stop magic smooth here,component:"<<component<<std::endl;
    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,20000,nodeToCheck,reply);     
    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeMagnetic, stop magic smooth failed"<<std::endl;
    }
    return Status::OK;
  }

  Status ShakeHeatMagnetic(ServerContext* context, const ShakeHeatMagneticParam* request, CmdResponse* reply ) override {
#if 1    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_HEAT_CTL;
    std::cout<<"enter in ShakeHeatMagnetic"<<std::endl;
    
    int component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.
    int actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
    
    heat_ctl stHeatCtl;
    stHeatCtl.chanNum = component;
    stHeatCtl.isClose = 0;
    stHeatCtl.temperature = request->heattemp();

    sendToActAndWaitResp(&msgHeadToSend, &stHeatCtl,5000,nodeToCheck,reply);

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeHeatMagnetic, start heating failed"<<std::endl;
      return Status::OK;
    }
    

    //2, start shake here;
        //sockActMsg msgHeadToSend;

    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;
    
    component = request->index();

    //component 0--4 is for magnet smooth
    //component 16--20 is for shake.

    //if(request->oper() == GPRPC::SHAKE)
    //{
    component += 16;
    //}
    actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
  

    //sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }


    switch_ctl switchCtl;
    switchCtl.chanNum = component;
    switchCtl.isClose = 0;
    switchCtl.duration = 0;//request->shaketime();


    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeHeatMagnetic, start shake failed"<<std::endl;
      return Status::OK;
    }
    //3,sleep here
    int time_ms_to_shake = request->shaketime();
    if(time_ms_to_shake <= 500)
    {
       time_ms_to_shake = 5000;
    }
    usleep(1000*(time_ms_to_shake-500));
    //3.1 stop shake here;
    switchCtl.chanNum = component;
    switchCtl.isClose = 1;
    switchCtl.duration = 0;//request->shaketime();

    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeHeatMagnetic, stop shake failed"<<std::endl;
      return Status::OK;
    }
    //std::cout<<"stop shake success"<<std::endl;
    //4,start smooth here

    component = request->index();
    actId = calcActId(MODULE_SHAKE,msgHeadToSend.actType,component);
  

    //sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SHAKE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SHAKE_CTL;

    switchCtl.chanNum = component;
    switchCtl.isClose = 0;
    switchCtl.duration = 0;//request->magnetictime();//request->shaketime();
    std::cout<<"start magic smooth here,component:"<<component<<std::endl;
    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,20000,nodeToCheck,reply);     
    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"in ShakeHeatMagnetic, start magic smooth failed"<<std::endl;
      return Status::OK;
    }
    int time_ms_magic = request->magnetictime();
    if(time_ms_magic <= 500)
    {
      time_ms_magic = 5000;
    }
    usleep((time_ms_magic-500)*1000);
#else
    sleep(30);
    reply->set_returnval(GPRPC::ReturnVal::RET_TRUE);
#endif
    return Status::OK; 
  } 

  Status HeatSealHeating(ServerContext* context, const HeatTemp* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SEAL;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_HEAT_CTL;
    std::cout<<"enter in HeatSealHeating"<<std::endl;
    // if(request->oper() == GPRPC::SHAKE)
    // {
    //   msgHeadToSend.actType = ACT_SHAKE_CTL;
    // }
    // else if(request->oper() == GPRPC::MAGNETIC)
    // {
    //   msgHeadToSend.actType = ACT_SINGLE_MOVE;
    // }
    
    int component = SEAL_CHAN_SEAL;

    int actId = calcActId(MODULE_SEAL,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
    
    heat_ctl stHeatCtl;
    stHeatCtl.chanNum = component;
    stHeatCtl.isClose = (request->heatswitch() == GPRPC::CLOSE)?1:0;
    stHeatCtl.temperature = request->heattemp();
    printf("in ShakeHeatHeating,temperature:%f\n",stHeatCtl.temperature);
    sendToActAndWaitResp(&msgHeadToSend, &stHeatCtl,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;   
  } 

  Status HeatSealStart(ServerContext* context, const Void* request, CmdResponse* reply ) override {
	  sockActMsg msgHeadToSend;
	  memset(&msgHeadToSend,0,sizeof(sockActMsg));
	  msgHeadToSend.moduleType = MODULE_SEAL;//convertModule(request->moduletype());
	  msgHeadToSend.actType = ACT_CHAIN_ACTION;
	  msgHeadToSend.paramType = PARAM_SEAL_CTL;
	  
	  
	  int component = -1;
	  int actId = calcActId(MODULE_SEAL,msgHeadToSend.actType,component);
	  
	  
	  // if(!checkActReady(actId))
	  // {
	  //	reply->set_returnval(ReturnVal::RET_REJECT);
	  //	return Status::OK;
	  // }
	  
	  sock_act_ctl ctlData;
	  ctlData.actId = actId;
	  ctlData.expectDataType = EXPECT_NO_DATA;
	  ctlData.status = LUA_ACT_WAITING;
	  
	  act_ctl_node *nodeToCheck = setExpectData(&ctlData);
	  
	  if(nodeToCheck == NULL)
	  {
		//action already running.
		reply->set_returnval(ReturnVal::RET_REJECT);
		return Status::OK;
	  }
	  
	  //sendSockMsgToAct(&msgHeadToSend, request);
    int downSteps = -1;
	  sendToActAndWaitResp(&msgHeadToSend, &downSteps,30000,nodeToCheck,reply);
	  return Status::OK;
  } 

  Status HeatSeal(ServerContext* context, const HeatSealTestParam* request, CmdResponse* reply ) override {
	  sockActMsg msgHeadToSend;
	  memset(&msgHeadToSend,0,sizeof(sockActMsg));
	  msgHeadToSend.moduleType = MODULE_SEAL;//convertModule(request->moduletype());
	  msgHeadToSend.actType = ACT_CHAIN_ACTION;
	  msgHeadToSend.paramType = PARAM_SEAL_CTL;
	  
	  
	  int component = -1;
	  int actId = calcActId(MODULE_SEAL,msgHeadToSend.actType,component);
	  
	  
	  // if(!checkActReady(actId))
	  // {
	  //	reply->set_returnval(ReturnVal::RET_REJECT);
	  //	return Status::OK;
	  // }
	  
	  sock_act_ctl ctlData;
	  ctlData.actId = actId;
	  ctlData.expectDataType = EXPECT_NO_DATA;
	  ctlData.status = LUA_ACT_WAITING;
	  
	  act_ctl_node *nodeToCheck = setExpectData(&ctlData);
	  
	  if(nodeToCheck == NULL)
	  {
		//action already running.
		reply->set_returnval(ReturnVal::RET_REJECT);
		return Status::OK;
	  }
	  
	  //sendSockMsgToAct(&msgHeadToSend, request);
    int downSteps = request->high();
	  sendToActAndWaitResp(&msgHeadToSend, &downSteps,30000,nodeToCheck,reply);
	  return Status::OK;
  }

  // Status MetalBathHeating(ServerContext* context, const MetalBathHeatTemp* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status MetalBathCtrlSwitch(ServerContext* context, const QpcrSwitchCtrl* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status MetalBathAgeingTest(ServerContext* context, const MetalBathAgeingTestParam* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  Status OpenLidJawCtrl(ServerContext* context, const SwitchCtrl* request, CmdResponse* reply ) override {
    
    
    std::cout<<"enter in ModuleMove"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_OPEN_LID;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;

    int component = GPRPC::MotorType::MT_JAW;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    MotorPosParam requestMovePos;

    requestMovePos.set_moduletype(GPRPC::ModuleType::MT_OPEN_LID);
    requestMovePos.set_motortype(GPRPC::MotorType::MT_JAW);
    GPRPC::Position * pstPos = new GPRPC::Position;
    if(request->switch_() == GPRPC::Switch::CLOSE)
    {
        pstPos->set_postype(GPRPC::PosType::PT_OPEN_LID_Z_ClOSE);
    }
    else
    {
        pstPos->set_postype(GPRPC::PosType::PT_OPEN_LID_Z_OPEN);      
    }

    requestMovePos.set_allocated_pos(pstPos);

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &requestMovePos,20000,nodeToCheck,reply);

    requestMovePos.clear_pos();
    //requestMovePos.clear_moduletype();

    return Status::OK; 
  }

  Status OpenLidCtrl(ServerContext* context, const SwitchCtrl* request, CmdResponse* reply ) override {
	  sockActMsg msgHeadToSend;
	  memset(&msgHeadToSend,0,sizeof(sockActMsg));
	  msgHeadToSend.moduleType = MODULE_OPENLID;//convertModule(request->moduletype());
	  msgHeadToSend.actType = ACT_CHAIN_ACTION;
	  msgHeadToSend.paramType = PARAM_OPENLID_CTL;
	  
	  
	  int component = -1;
	  int actId = calcActId(MODULE_OPENLID,msgHeadToSend.actType,component);
	  
	  
	  // if(!checkActReady(actId))
	  // {
	  //	reply->set_returnval(ReturnVal::RET_REJECT);
	  //	return Status::OK;
	  // }
	  
	  sock_act_ctl ctlData;
	  ctlData.actId = actId;
	  ctlData.expectDataType = EXPECT_NO_DATA;
	  ctlData.status = LUA_ACT_WAITING;
	  
	  act_ctl_node *nodeToCheck = setExpectData(&ctlData);
	  
	  if(nodeToCheck == NULL)
	  {
		//action already running.
		reply->set_returnval(ReturnVal::RET_REJECT);
		return Status::OK;
	  }
	  
	  //sendSockMsgToAct(&msgHeadToSend, request);
	  sendToActAndWaitResp(&msgHeadToSend, request,40000,nodeToCheck,reply);
	  return Status::OK;
  }

  Status VerticalBarcodeScannerWork(ServerContext* context, const BarcodeScannerPos* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));

    if(request->scannertype() == GPRPC::ScannerType::REAGENT_CLEAN_SCANNER)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DP8;
    }
    else if(request->scannertype() == GPRPC::ScannerType::CONSUMABLE_PCR_SCANNER)
    {
        msgHeadToSend.moduleType = GPRPC::ModuleType::MT_DJ1_PCR_REAGENT;
    }
    else
    {
        reply->set_returnval(ReturnVal::RET_REJECT);
        return Status::OK;
    }

    //convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    ModuleMoveParam pstParam;
    Position * posTarget = new Position;
    posTarget->CopyFrom(request->pos());
    pstParam.set_allocated_pos(posTarget);
    pstParam.set_moduletype(GPRPC::ModuleType(msgHeadToSend.moduleType));


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &pstParam,20000,nodeToCheck,reply);


    pstParam.clear_pos();

    if(reply->returnval() != GPRPC::ReturnVal::RET_TRUE)
    {
      std::cout<<"VerticalBarcodeScannerWork, move to target failed\n"<<std::endl;
      return Status::OK;
    }

    msgHeadToSend.moduleType = MODULE_SCANCODE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SCANCODE_CTL;

    
    int component = 0;

    if(request->scannertype() == GPRPC::CONSUMABLE_PCR_SCANNER)
    {
        component = 2;
    }
    else if(request->scannertype() == GPRPC::REAGENT_CLEAN_SCANNER)
    {
        component = 3;
    }
    else
    {
        reply->set_returnval(ReturnVal::RET_REJECT);
        return Status::OK;
    }
    std::cout<<"component:"<<component<<std::endl;
    actId = calcActId(MODULE_SCANCODE,msgHeadToSend.actType,component);

    //sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    ScancodeParam stParam;
    int isStart = 1;

    stParam.set_scanid(GPRPC::scancodeChanId(component));
    stParam.set_isstart(isStart);


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &stParam,20000,nodeToCheck,reply);
    return Status::OK;
  } 


  Status HorBarcodeScannerSW(ServerContext* context, const ScannerSwParam* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SCANCODE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SCANCODE_CTL;

    
    int component = 0;

    if(request->scannertype() == GPRPC::REAGENT_PURIFY_SCANNER)
    {
        component = 0;
    }
    else if(request->scannertype() == GPRPC::SAMPLE_SCANNER)
    {
        component = 1;
    }
    else if(request->scannertype() == GPRPC::CONSUMABLE_PCR_SCANNER)
    {
        component = 2;
    }
    else if(request->scannertype() == GPRPC::REAGENT_CLEAN_SCANNER)
    {
        component = 3;
    }
    std::cout<<"component:"<<component<<std::endl;
    int actId = calcActId(MODULE_SCANCODE,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    ScancodeParam stParam;
    int isStart = 0;
    if(request->sw() == GPRPC::OPEN)
    {
      isStart = 1;
    }
    else
    {
      isStart = 0; 
    }
    stParam.set_scanid(GPRPC::scancodeChanId(component));
    stParam.set_isstart(isStart);


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &stParam,20000,nodeToCheck,reply);
    return Status::OK;
  } 

  // Status OpticCtrlLight(ServerContext* context, const QpcrSwitchCtrl* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status OpticRebootCamera(ServerContext* context, const ModuleName* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status OpticChangeChannel(ServerContext* context, const Channel* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status OpticTakePictures(ServerContext* context, const TakePictures* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  // Status OpticChangeChannTakePict(ServerContext* context, const ChangeChannTakePictParam* request, CmdResponse* reply ) override {
  //   return Status::OK;
  // }

  Status SCanCode_ctl(ServerContext* context, const ScancodeParam* request, CmdResponse* reply ) override {
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_SCANCODE;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SCANCODE_CTL;

    
    int component = request->scanid();
    int actId = calcActId(MODULE_SCANCODE,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);
    return Status::OK;
  }

  Status DrawerMagLockCtl(ServerContext* context, const DrawerMagLockParam* request, CmdResponse* reply ) override {
        sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = MODULE_DRAWER;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_DRAWER_CTL;
    msgHeadToSend.paramType = request->drawer();
    
    int component = request->drawer();
    int actId = calcActId(MODULE_DRAWER,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);
    return Status::OK;
  }

};

extern int convertPosQpcr(const Position& grpcPos,location_layout * locOut);

class PMSServiceImpl final : public PMSService::Service {

  int m_currChannelQpcr1 = 0;
  int m_currChannelQpcr2 = 0;
 
  Status OpticChangeChannel(ServerContext* context,const GPRPC::Channel* request, CmdResponse* reply) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    int component = 0;
    msgHeadToSend.moduleType = request->qpcrmodule();

    std::cout<< "enter in OpticChangeChannel"<<std::endl;
    
    if(  msgHeadToSend.moduleType != GPRPC::ModuleType::MT_QPCR1
      && msgHeadToSend.moduleType != GPRPC::ModuleType::MT_QPCR2)
    {
      std::cout<<"module type is not valid"<<msgHeadToSend.moduleType<<std::endl;
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    qpcr_move stQpcrMove; 
    
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());
    component = MT_OPTICAL;

    stQpcrMove.motorType = MT_OPTICAL;
    stQpcrMove.pos = -1;

    //if(request->channelnum() == GPRPC::ChannelNum::OPTICS_CHANNEL_FAM)
    switch(request->channelnum())
    {
      case GPRPC::ChannelNum::OPTICS_CHANNEL_FAM:
      stQpcrMove.pos = OPTICS_CHANNEL5_FAM;
      break;
      case GPRPC::ChannelNum::OPTICS_CHANNEL_HEX:
      stQpcrMove.pos = OPTICS_CHANNEL4_HEX;
      break;
      case GPRPC::ChannelNum::OPTICS_CHANNEL_TAMRA:
      stQpcrMove.pos = OPTICS_CHANNEL3_TAMRA;
      break;
      case GPRPC::ChannelNum::OPTICS_CHANNEL_ROX:
      stQpcrMove.pos = OPTICS_CHANNEL2_ROX;
      break;
      case GPRPC::ChannelNum::OPTICS_CHANNEL_CY5:
      stQpcrMove.pos = OPTICS_CHANNEL1_CY5;
      break;
      default:
      break;
    }
    if(stQpcrMove.pos < 0)
    {
      std::cout<<"channum error, channum:"<<request->channelnum()<<std::endl;
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;
    }
    //stQpcrMove.pos = request->channelnum();
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;

    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }
    
    if(msgHeadToSend.moduleType == GPRPC::ModuleType::MT_QPCR1)
    {
        m_currChannelQpcr1 = request->channelnum();
    }
    else
    {
        m_currChannelQpcr2 = request->channelnum();      
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    
    
    sendToActAndWaitResp(&msgHeadToSend, &stQpcrMove,10000,nodeToCheck,reply);

    return Status::OK;
  }

  Status GetCameraChannel(ServerContext* context,const GPRPC::ModuleName* request, GPRPC::Channel* reply) override {

    if(request->moduletype()==GPRPC::ModuleType::MT_QPCR1)
    {
        reply->set_channelnum(GPRPC::ChannelNum(m_currChannelQpcr1));
    }
    else if(request->moduletype()==GPRPC::ModuleType::MT_QPCR2)
    {
        reply->set_channelnum(GPRPC::ChannelNum(m_currChannelQpcr2)); 
    }

    return Status::OK;    
  }

  Status OpticCtrlLight(ServerContext* context,const GPRPC::OpticCtrlLightParam* request, CmdResponse* reply) override {

    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    
    msgHeadToSend.moduleType = convertModule(request->qpcrmodule());//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_LIGHT_CTL;
    std::cout<<"enter in OpticCtrlLight"<<std::endl;
    if(request->qpcrmodule()!=GPRPC::ModuleType::MT_QPCR1
    &&request->qpcrmodule()!=GPRPC::ModuleType::MT_QPCR2)
    {
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;
    }

    int component = LIGHT_QPCR_SOURCE;
    
    if(request->lighttype() == GPRPC::LIGHT_CAMERA)
    {
      component = LIGHT_QPCR_SOURCE;
    }
    else 
    {
      component = LIGHT_QPCR_LIGHTING;
    }

    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }


    switch_ctl switchCtl;
    switchCtl.chanNum = component;
    if(request->switch_() == GPRPC::Switch::CLOSE)
    {
        switchCtl.isClose = 1;
    }
    else
    {
        switchCtl.isClose = 0;
    }

    switchCtl.duration = 0;

    sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);

    return Status::OK;    
  }

  Status MetalBathHeating(ServerContext* context,const GPRPC::MetalBathHeatTemp* request, CmdResponse* reply) override {

        sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    
    msgHeadToSend.moduleType = convertModule(request->qpcrmodule());//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_HEAT_CTL;
    std::cout<<"enter in MetalBathHeating"<<std::endl;
    
    int component = BATH_HEAT_BLOCK;//0 is for metalbath, 1, is for hotlid

    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
    heat_ctl heatCtlParam; 

    heatCtlParam.chanNum = component;
    if(request->heatswitch() == GPRPC::Switch::CLOSE)
    {
        heatCtlParam.isClose = 1;
    }
    else
    {
        heatCtlParam.isClose = 0;
        //parseQpcrScheme(request->scheme());
    }

    heatCtlParam.temperature = request->heattemp();

    sendToActAndWaitResp(&msgHeadToSend, &heatCtlParam,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;    
  }

  Status MetalBathHotLidSwitch(ServerContext* context,const GPRPC::QpcrSwitchCtrl* request, CmdResponse* reply) override {

    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    
    msgHeadToSend.moduleType = convertModule(request->qpcrmodule());//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_HEAT_CTL;
    std::cout<<"enter in MetalBathHotLidSwitch"<<std::endl;
    
    int component = BATH_HEAT_HOTLID;//0 is for metalbath, 1, is for hotlid

    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
    heat_ctl heatCtlParam; 

    heatCtlParam.chanNum = component;
    if(request->switch_() == GPRPC::Switch::CLOSE)
    {
        heatCtlParam.isClose = 1;
    }
    else
    {
        heatCtlParam.isClose = 0;
        //parseQpcrScheme(request->scheme());
    }

    heatCtlParam.temperature = request->temp();
    
    sendToActAndWaitResp(&msgHeadToSend, &heatCtlParam,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;    
  }

  Status MoveLogistics3Tray(ServerContext* context, const PosTypeParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in MoveLogistics3Tray"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = GPRPC::ModuleType::MT_LOGISTICS;//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_LOGISTIC_MOVE;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    logistic_move logMoveParam;
    logMoveParam.submodule = SUB_MODULE_LOG3;

    int convertRet = convertLogicPostype(logMoveParam.submodule,request->postype());
    if(convertRet < 0)
    {
      std::cout<<"convert logistic pos type failed"<<std::endl;
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;      
    }
    logMoveParam.posTypeInner = convertRet;


    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &logMoveParam,20000,nodeToCheck,reply);

    return Status::OK; 
  }

  Status JawGetPut(ServerContext* context, const JawGetPutParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in JawGetPut"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_CTL;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);    
    return Status::OK;
  }
  Status JawMove(ServerContext* context, const JawMoveParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in JawMove"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_JAW_TRANS;
    msgHeadToSend.paramType = PARAM_JAW_TRANS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,60000,nodeToCheck,reply);
    
    return Status::OK;
  }

  Status SendQpcrScheme(ServerContext* context,const QpcrSchemeParam* request, CmdResponse* reply) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    
    msgHeadToSend.moduleType = convertModule(request->qpcrmodule());//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SCHEME_CTL;
    std::cout<<"enter in SendQpcrScheme"<<std::endl;

    //parseQpcrScheme(*request);
    // if(request->oper() == GPRPC::SHAKE)
    // {
    //   msgHeadToSend.actType = ACT_SHAKE_CTL;
    // }
    // else if(request->oper() == GPRPC::MAGNETIC)
    // {
    //   msgHeadToSend.actType = ACT_SINGLE_MOVE;
    // }
    
    int component = -1;

    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
       switch_ctl switchCtl;
       switchCtl.chanNum = component;
       switchCtl.isClose = 0;
       switchCtl.duration = 0;
    
       sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;   
    
  }


  Status MetalBathTest(ServerContext* context,const MetalBathSW* request, CmdResponse* reply) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    
    msgHeadToSend.moduleType = convertModule(request->scheme().qpcrmodule());//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SCHEME_CTL;
    std::cout<<"enter in MetalBathTest"<<std::endl;

    //parseQpcrScheme(request->scheme());
    // if(request->oper() == GPRPC::SHAKE)
    // {
    //   msgHeadToSend.actType = ACT_SHAKE_CTL;
    // }
    // else if(request->oper() == GPRPC::MAGNETIC)
    // {
    //   msgHeadToSend.actType = ACT_SINGLE_MOVE;
    // }
    
    int component = -1;

    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    // if(msgHeadToSend.actType == ACT_SHAKE_CTL)
    // {
       switch_ctl switchCtl;
       switchCtl.chanNum = component;
       if(request->sw() == GPRPC::Switch::CLOSE)
       {
           switchCtl.isClose = 1;
       }
       else
       {
           switchCtl.isClose = 0;
           parseQpcrScheme(request->scheme());
       }

       switchCtl.duration = 0;
    
       sendToActAndWaitResp(&msgHeadToSend, &switchCtl,5000,nodeToCheck,reply);
    // }
    // else if(msgHeadToSend.actType == ACT_SINGLE_MOVE)
    // {
    //    sendToActAndWaitResp(&msgHeadToSend, request,10000,nodeToCheck,reply);
    // }
    return Status::OK;   
    
  }

  Status MotorInit(ServerContext* context, const Motor* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in MotorInit"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SINGLE_INIT;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int component = request->motortype();
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;
  }

  Status MotorMove(ServerContext* context,const MotorMoveParam* request, CmdResponse* reply) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    int component = 0;
    msgHeadToSend.moduleType = request->moduletype();
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());
    component = request->motortype();
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_STEPS;
    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,5000,nodeToCheck,reply);

    return Status::OK;
  }

    Status ModuleInit(ServerContext* context, const ModuleName* request, CmdResponse* reply ) override {
    
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_MODULE_INIT;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;

    if(request->moduletype() == GPRPC::ModuleType::MT_QPCR1 
       || request->moduletype() == GPRPC::ModuleType::MT_QPCR2)
    {
        if(request->qpcrtype() == GPRPC::QpcrType::QM_OPTICS)
        {
            GPRPC::Motor motorParam;
            motorParam.set_moduletype(request->moduletype());
            motorParam.set_motortype(GPRPC::MotorType::MT_CHANNEL); 
            return MotorInit(context,&motorParam,reply);
        }

    }
    int component = -1;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK;
  }

  Status ModuleMove(ServerContext* context, const ModuleMoveParam* request, CmdResponse* reply ) override {
    std::cout<<"enter in ModuleMove"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_PARRAL_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,-1);
    
    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);

    return Status::OK; 
  }
  Status MotorPos(ServerContext* context, const MotorPosParam* request, CmdResponse* reply ) override {
    
    std::cout<<"enter in MotorPos"<<std::endl;
    sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    msgHeadToSend.moduleType = request->moduletype();//convertModule(request->moduletype());
    msgHeadToSend.actType = ACT_SINGLE_MOVE;
    msgHeadToSend.paramType = PARAM_AXIS_MOVE_POS;
    int component = request->motortype();
    int actId = calcActId(convertModule(msgHeadToSend.moduleType),msgHeadToSend.actType,component);
    

    // if(!checkActReady(actId))
    // {
    //    reply->set_returnval(ReturnVal::RET_REJECT);
    //    return Status::OK;
    // }

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    if(request->moduletype() == GPRPC::ModuleType::MT_QPCR1
    ||request->moduletype() == GPRPC::ModuleType::MT_QPCR2)
    {
        qpcr_move stQpcrMove; 
        
        msgHeadToSend.actType = ACT_SINGLE_MOVE;
        //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());

        stQpcrMove.motorType = component;
        location_layout locLayout;
        memset(&locLayout,0,sizeof(location_layout));
        stQpcrMove.pos = convertPosQpcr(request->pos(),&locLayout);

        if(stQpcrMove.pos == 0)
        {
          stQpcrMove.pos = locLayout.location_type;
        }
        else
        {
          std::cout<<"convert Qpcr pos failed"<<std::endl;
          reply->set_returnval(GPRPC::ReturnVal::RET_FALSE);
        }

        sendToActAndWaitResp(&msgHeadToSend, &stQpcrMove,20000,nodeToCheck,reply);
    }
    else
    {
        //sendSockMsgToAct(&msgHeadToSend, request);
        sendToActAndWaitResp(&msgHeadToSend, request,20000,nodeToCheck,reply);
    }

    return Status::OK;
    
  }

  Status QpcrGetTempSW(ServerContext* context, const GetQpcrTempSWParam* request, CmdResponse* reply ) override {
        sockActMsg msgHeadToSend;
    memset(&msgHeadToSend,0,sizeof(sockActMsg));
    int component = 0;

    if(request->module() == GPRPC::ModuleType::MT_QPCR1)
    {
      msgHeadToSend.moduleType = MODULE_QPCR1;
    }
    else if(request->module() == GPRPC::ModuleType::MT_QPCR2)
    {
      msgHeadToSend.moduleType = MODULE_QPCR2;      
    }
    else
    {
      reply->set_returnval(ReturnVal::RET_FALSE);
      return Status::OK;
    }
    //convertTempPos(request->tempos(),msgHeadToSend.moduleType,component);
    //msgHeadToSend.moduleType = convertTempPos;//convertModule(request->moduletype());
    component = -1;
    msgHeadToSend.actType = ACT_TEMPERATURE_READ;
    msgHeadToSend.paramType = component;
    int actId = calcActId(msgHeadToSend.moduleType,msgHeadToSend.actType,component);

    sock_act_ctl ctlData;
    ctlData.actId = actId;
    ctlData.expectDataType = EXPECT_NO_DATA;
    ctlData.status = LUA_ACT_WAITING;

    act_ctl_node *nodeToCheck = setExpectData(&ctlData);

    if(nodeToCheck == NULL)
    {
      //action already running.
      reply->set_returnval(ReturnVal::RET_REJECT);
      return Status::OK;
    }

    GetTempParam getTempParam;
    getTempParam.set_switch_(request->switch_());
    getTempParam.set_intervaltime(request->interval());

    //sendSockMsgToAct(&msgHeadToSend, request);
    sendToActAndWaitResp(&msgHeadToSend, &getTempParam,5000,nodeToCheck,reply);

    return Status::OK;
  }

 
};

#ifdef _QPCR
#define IPPORT_STR  "0.0.0.0:50069"
#else
#define IPPORT_STR  "0.0.0.0:50068"
#endif
Server * ptrServer;
void RunServer() {
  std::string server_address(IPPORT_STR);

  DCSServiceImpl serviceDCS;

  PMSServiceImpl servicePMS;

  ServerBuilder builder;
  // Listen on the given address without any authentication mechanism.
  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
  // Register "service" as the instance through which we'll communicate with
  // clients. In this case it corresponds to an *synchronous* service.

  builder.RegisterService(&serviceDCS);

  builder.RegisterService(&servicePMS);
  // Finally assemble the server.
  std::unique_ptr<Server> server(builder.BuildAndStart());
  std::cout << "Server listening on " << server_address << std::endl;

  // Wait for the server to shutdown. Note that some other thread must be
  // responsible for shutting down the server for this call to ever return.
  ptrServer= server.get();
  server->Wait();  
}


extern int initLuaActMsg(void);

extern int deinitLuaActMsg(void);

extern int msgProc_exitFlag;
extern int sock_exitFlag;
void handler(int data)
{ 
    printf("sig is %d\n", data);
    
    ptrServer->Shutdown();
    msgProc_exitFlag = 1;
    sock_exitFlag = 1;
    clear_msg_buff_list();
    clearCtlTable();
    //deinitLuaActMsg();
    system("exit 0");
}



int main(int argc, char** argv) {
  //initLuaActMsg();
  initCtlTable();
  init_msg_buff_list();

  //initSockServer(1);
  signal(SIGTERM, handler);

  
  RunServer();

  return 0;
}
